package org.zebra.captcha.sms;

import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.dromara.sms4j.api.SmsBlend;
import org.dromara.sms4j.api.entity.SmsResponse;
import org.dromara.sms4j.core.factory.SmsFactory;
import org.zebra.cache.util.RedisUtil;
import org.zebra.captcha.CaptchaHandler;

import java.time.Duration;
import java.util.LinkedHashMap;

/**
 * 短信验证码
 *
 * @author zhanghongbin
 */
@Slf4j
public class SmsCaptchaHandler implements CaptchaHandler<Boolean> {

    private int expirationTime;
    private int codeLength;
    private SmsCaptchaTemplateSource smsCaptchaTemplateSource;

    public SmsCaptchaHandler(int expirationTime, int codeLength, SmsCaptchaTemplateSource smsCaptchaTemplateSource) {
        this.expirationTime = expirationTime;
        this.codeLength = codeLength;
        this.smsCaptchaTemplateSource = smsCaptchaTemplateSource;
    }

    @Override
    public Boolean build(String name) {
        if (this.smsCaptchaTemplateSource == null) {
            throw ExceptionUtil.wrapRuntime("没有SmsTemplateSource对象");
        }
        String key = CAPTCHA_KEY + name;
        String code = RandomUtil.randomNumbers(this.codeLength);
        RedisUtil.setCacheObject(RedisUtil.getRedisTemplate(), key, code, Duration.ofMinutes(this.expirationTime));
        LinkedHashMap<String, String> map = new LinkedHashMap<>(1);
        map.put(smsCaptchaTemplateSource.getCodeVariableName(), code);
        map.put(smsCaptchaTemplateSource.getExpirationTimeVariableName(), String.valueOf(expirationTime));
        try {
            SmsBlend smsBlend = SmsFactory.getSmsBlend(smsCaptchaTemplateSource.getConfigId());
            SmsResponse smsResponse = smsBlend.sendMessage(name, this.smsCaptchaTemplateSource.getTemplateId(), map);
            return smsResponse.isSuccess();
        } catch (Exception e) {
            log.info("短信发送失败", e);
        }
        return false;
    }

    @Override
    public boolean check(String name, String code) {
        String verifyKey = CAPTCHA_KEY + name;
        String captcha = RedisUtil.getCacheObject(RedisUtil.getRedisTemplate(), verifyKey);
        RedisUtil.delete(RedisUtil.getRedisTemplate(), verifyKey);
        if (StrUtil.isBlank(captcha)) {
            return false;
        }
        return code.equals(captcha);
    }
}
